#ifndef _ENCODING_MANAGER_H
#define _ENCODING_MANAGER_H

#include <fonts_manager.h>
#include <disp_manager.h>

typedef struct EncodingOpr
{
    char *name;                                                                                            // 编码模块的名字
    int iHeadLen;                                                                                          // 文件名的长度，
    PT_FontOpr ptFontOprSupportedHead;                                                                     // 把支持编码的字体模块，放在这个链表里
    int (*isSupport)(unsigned char *pucBufHead);                                                           // 用这个函数来判断是否支持某个文件
    int (*GetCodeFrmBuf)(unsigned char *purBufssssStart, unsigned char *pucBufEnd, unsigned int *pdwCode); // 取出一个字符的编码值
    struct  EncodingOpr *ptNext;                                                                               // 链表
} T_EncodingOpr, *PT_EncodingOpr;

// 注册编码模块，一行文字可能用ASCII编码，也可能用UTF8编码，怎么从一行文字中取出一个字，不同的编码取法不一样
// 输出参数：ptEncodingOpr--一个结构体，包含某种编码方式的操作函数
// 返回值：0-成功，其他值-失败
int RegisterEncodingOpr(PT_EncodingOpr ptEncodingOpr);

PT_EncodingOpr Encode(char *pcName);

// 显示本程序能支持的编码方式
void ShowEncodingOpr(void);

// 功能：根据名字取出指定的显示模块
PT_DispOpr GetDispOpr(char *pcName);

// 给文件选择一个编码模块
// 输出参数：pucFileBufHead--文件头部，即调用mmap映射文件所得到的内存指针
// 返回值：NULL--现有的编码方式不支持该文件，非NULL-对应编码方式的结构体指针
PT_EncodingOpr SelectEncodingOprForFile(unsigned char *pucFileBufHead);

// 功能描述：1.字符的编码值, 即这个文件用什么数值来表示, 比如'A'用0x41来表示,
//   *               '中'的编码方式有多种, GBK编码方式里它的数值为0xD0D6, 而在UNICODE
//   *               编码里它的数值为0x4E2D
//   *          2. 编码值的表示方式, 比如UTF8/UTF16LE/UTF16BE是UNICODE编码的三种表示方式,例如:
//   *               'A'的ASCII表示为0x41;UTF16-LE表示为0x41,0x00;UTF16-BE表示为0x00,0x41;UTF8表示为0x41
//   *               '中'的GBK表示为0xD6,0xD0;UTF16-LE表示为0x2D,0x4E;UTF16-BE表示为0x4E,0x2D;UTF8表示为0xE4,0xB8,0xAD
//   *               注意:UTF8/UTF16LE/UTF16BE只是UNICODE编码的不同表示方式,对于同一个字符,它们表达的编码值是一样的,只是表示方法不同
//   *           3. 字符的位图,即字符应该怎么描画
//   *            举例: 使用freetype矢量字库来显示UTF8编码格式的文件内容时,
//   *                  我们要先取出UTF8的值用来解析出UNICODE值,然后根据UNICODE值去字库文件中取出位图,
//   *                  最后在LCD上显示出来
//   *             4.比如它要么是ANSI(字母用ASCII,汉字用GBK),要么是UTF8等等; 文件里字符的位图来源可以有多种,
//   *        比如ASCII字符可以从确定的数组中获得它的位图, GBK字符可以从"HZK16"这个文件中获得它的位图,
//   *        也可以从某个freetype矢量字库中获得它的位图.
//   *           AddFontOprForEncoding函数就是给某个编码方式(ptEncodingOpr)提供字符的处理方法(ptFontOpr),
//   *        ptFontOpr将被放入"ptEncodingOpr->ptFontOprSupportedHead"链表中
// 输入参数： ptEncodingOpr--编码方式,ptFontOpr--字符处理结构体，内含”GetFontBitmap“（即根据编码值获得位图）
// 返回值：0-成功，-1-失败
int AddFontOprEncoding(PT_EncodingOpr ptEncodingOpr, PT_FontOpr ptFontOpr);

// AddFontOprForEncoding的反函数，删除ptFontOprSupport的结构体
// 输入参数：ptEncodingOpr--编码方式,ptFontOpr--字符处理结构体，内含GetFontBitmap函数，根据编码值获得位图
// 返回值：0-成功，-1-失败
int DelFontOprFrmEncoding(PT_EncodingOpr ptEncodingOpr, PT_FontOpr ptFontOpr);

// 调用各种编码的初始化函数
// 返回值：0-成功，其他值-失败
int EncodingInit(void);

//  * 功能描述： 根据字符的ANSI编码值,有freetype/ascii/gbk这三种方法获得它的字符位图
//  *            AsciiEncodingInit先给g_tAsciiEncodingOpr添加freetype/ascii/gbk这三种PT_FontOpr结构体;
//  *            最后注册g_tAsciiEncodingOpr
// 返回值：0-成功，其他值-失败
int AsciiEncodingInit(void);

//  * 功能描述： 根据字符的UNICODE编码值,有freetype/ascii这2种方法获得它的字符位图
//  *            Utf16beEncodingInit先给g_tUtf16beEncodingOpr添加freetype/ascii这2种PT_FontOpr结构体;
//  *            最后注册g_tUtf16beEncodingOpr
// 返回值：0-成功，其他值-失败
int Utf16beEncodingInit(void);

//  * 功能描述： 根据字符的UNICODE编码值,有freetype/ascii这2种方法获得它的字符位图
//  *            Utf16leEncodingInit先给g_tUtf16leEncodingOpr添加freetype/ascii这2种PT_FontOpr结构体;
//  *            最后注册g_tUtf16leEncodingOpr
// 返回值：0-成功，其他值-失败
int Utf16beEncodingInit(void);

//  * 功能描述： 根据字符的UNICODE编码值,有freetype/ascii这2种方法获得它的字符位图
//  *            Utf8EncodingInit先给g_tUtf8EncodingOpr添加freetype/ascii这2种PT_FontOpr结构体;
//  *            最后注册g_tUtf8EncodingOpr
// 返回值：0-成功，其他值-失败
int Utf8beEncodingInit(void);

//  * 功能描述： 从字符串中取出UTF8格式的字符串的UNICODE编码值
//  * 输入参数： pucBufStart - 字符串起始位置
//  *            pucBufEnd   - 字符串结束位置(这个位置的字符不处理)
//  * 输出参数： pdwCode     - 所取出的编码值存在这里
//  * 返 回 值： 使用了多少个字符才得到这个编码值
int GetCodeFrmBuf(unsigned char *pucBufStart, unsigned char *pucBufEnd, unsigned int *pdwCode);

#endif /* _ENCODING_MANAGER_H */